package org.yunai.swjg.server.module.quest;

import org.yunai.swjg.server.entity.DoingQuestEntity;
import org.yunai.swjg.server.entity.FinishedQuestEntity;
import org.yunai.swjg.server.module.player.vo.Player;
import org.yunai.swjg.server.module.quest.vo.DoingQuest;
import org.yunai.swjg.server.module.quest.vo.FinishedQuest;
import org.yunai.swjg.server.rpc.message.S_C.S_C_QuestListResp;
import org.yunai.swjg.server.rpc.struct.StQuestInfo;
import org.yunai.yfserver.spring.BeanManager;

import java.util.*;

/**
 * 玩家任务日志
 * User: yunai
 * Date: 13-5-9
 * Time: 下午6:57
 */
public class QuestDiary {

    private static DoingQuestMapper doingQuestMapper;
    private static FinishedQuestMapper finishedQuestMapper;
    private static QuestService questService;
    static {
        doingQuestMapper = BeanManager.getBean(DoingQuestMapper.class);
        finishedQuestMapper = BeanManager.getBean(FinishedQuestMapper.class);
        questService = BeanManager.getBean(QuestService.class);
    }

    /**
     * 玩家信息
     */
    private Player player;
    /**
     * 进行中的任务集合
     */
    private Map<Integer, DoingQuest> doingQuests;
    /**
     * 完成的任务集合
     */
    private Map<Integer, FinishedQuest> finishedQuests;

    public QuestDiary(Player player) {
        this.player = player;
    }

    /**
     * 加载玩家任务信息
     */
    public void load() {
        // 加载正在进行中的任务
        List<DoingQuestEntity> doingQuestEntities = doingQuestMapper.selectList(player.getId());
        doingQuests = new HashMap<>(doingQuestEntities.size());
        for (DoingQuestEntity entity : doingQuestEntities) {
            DoingQuest doingQuest = DoingQuest.build(player, entity, questService.getQuest(entity.getQuestId()));
            doingQuests.put(entity.getQuestId(), doingQuest);
        }
        // 加载完成的任务
        List<FinishedQuestEntity> finishedQuestEntities = finishedQuestMapper.selectList(player.getId());
        finishedQuests = new HashMap<>(finishedQuestEntities.size());
        for (FinishedQuestEntity entity : finishedQuestEntities) {
            FinishedQuest finishedQuest = FinishedQuest.build(player, entity, questService.getQuest(entity.getQuestId()));
            finishedQuests.put(entity.getQuestId(), finishedQuest);
        }
    }

    /**
     * 发送任务所有信息<br />
     * 目前信息有：进行中的任务的任务列表 + 可接受的任务列表
     */
    public void noticeInfo() {
        List<StQuestInfo> questInfos = new ArrayList<>(doingQuests.size() + 10);
        for (AbstractQuest quest : questService.getAllQuest()) {
            // 进行中任务的任务详细信息
            DoingQuest doingQuest = doingQuests.get(quest.getId());
            if (doingQuest != null) {
                questInfos.add(quest.genDoingQuestInfo(player, doingQuest));
                continue;
            }
            // 可以接受的任务的任务详细信息
            StQuestInfo canAcceptQuestInfo = quest.genCanAcceptQuestInfo(player);
            if (canAcceptQuestInfo != null) {
                questInfos.add(canAcceptQuestInfo);
            }
        }
        player.message(new S_C_QuestListResp(questInfos));
    }

    /**
     * @return 正在进行中任务数量
     */
    public Integer getDoingQuestCount() {
        return doingQuests.size();
    }

    /**
     * @param condition 完成条件类型
     * @param subject 主体
     * @return 包含某个完成条件类型+主体的进行中任务
     */
    public List<DoingQuest> getDoingQuests(QuestDef.Condition condition, Integer subject) {
        if (getDoingQuestCount() == 0) {
            return Collections.emptyList();
        }
        List<DoingQuest> doingQuestList = new ArrayList<>(1);
        for (DoingQuest doingQuest : doingQuests.values()) {
            if (doingQuest.containFinishedCondition(condition, subject)) {
                doingQuestList.add(doingQuest);
            }
        }
        return doingQuestList;
    }

    /**
     * 获得进行中的任务的任务逻辑对象
     *
     * @param questId 任务模版编号
     * @return 任务逻辑对象
     */
    public AbstractQuest getDoingQuest(Integer questId) {
        DoingQuest doingQuest = doingQuests.get(questId);
        return doingQuest != null ? doingQuest.getQuest() : null;
    }

    /**
     * 获得进行中的任务信息
     *
     * @param questId 任务模版编号
     * @return 进行中的任务信息
     */
    public DoingQuest getDoingQuestInfo(Integer questId) {
        return doingQuests.get(questId);
    }

    /**
     * 添加进行中的任务信息
     *
     * @param doingQuest 进行中的任务信息
     */
    public void addDoingQuestInfo(DoingQuest doingQuest) {
        doingQuests.put(doingQuest.getQuest().getId(), doingQuest);
    }

    /**
     * 移除进行中的任务，并返回该任务信息
     *
     * @param questId 任务模版编号
     * @return 进行中的任务信息
     */
    public DoingQuest removeDoingQuestInfo(Integer questId) {
        return doingQuests.remove(questId);
    }

    /**
     * 获得完成的任务的任务逻辑对象
     *
     * @param questId 任务编号
     * @return 任务逻辑对象
     */
    public AbstractQuest getFinishedQuest(Integer questId) {
        FinishedQuest finishedQuest = finishedQuests.get(questId);
        return finishedQuest != null ? finishedQuest.getQuest() : null;
    }

    /**
     * 获得完成的任务信息
     *
     * @param questId 任务编号
     * @return 完成的任务信息
     */
    public FinishedQuest getFinishedQuestInfo(Integer questId) {
        return finishedQuests.get(questId);
    }

    /**
     * 添加完成的任务信息
     *
     * @param finishedQuest 完成的任务信息
     */
    public void addFinishedQuestInfo(FinishedQuest finishedQuest) {
        finishedQuests.put(finishedQuest.getQuest().getId(), finishedQuest);
    }

    /**
     * 获得指定任务的完成任务条件某个主体的完成数量
     *
     * @param questId   任务编号
     * @param condition 完成条件
     * @param subject   主体
     * @return 完成数量
     */
    public Integer getFinishedCount(Integer questId, QuestDef.Condition condition, Integer subject) {
        DoingQuest doingQuest = doingQuests.get(questId);
        return doingQuest.getFinishedCount(condition, subject);
    }

}
